package com.xoms.admin.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xoms.admin.aspect.datasource.DataSourceSwitcher;
import com.xoms.admin.cache.dao.ProCategoryCache;
import com.xoms.admin.cache.dao.ProductCache;
import com.xoms.admin.controller.res.bean.RProGroupBean;
import com.xoms.admin.controller.res.bean.RProJSONBean;
import com.xoms.admin.controller.res.bean.RProSelectJSONBean;
import com.xoms.admin.controller.res.bean.RProductBean;
import com.xoms.admin.controller.res.bean.RProductDetailBean;
import com.xoms.admin.model.AccountBean;
import com.xoms.admin.model.ProGroupBean;
import com.xoms.admin.model.ProductBean;
import com.xoms.admin.model.vo.BatchProGroupBean;
import com.xoms.admin.model.vo.ProTreeNodeBean;
import com.xoms.admin.model.vo.ProductDetailBean;
import com.xoms.admin.model.vo.TreeNodeBean;
import com.xoms.admin.persist.dao.ProCategoryDao;
import com.xoms.admin.persist.dao.ProStockDao;
import com.xoms.admin.persist.dao.ProductDao;
import com.xoms.admin.service.ProductService;
import com.xoms.admin.service.exception.ServiceException;
import com.xoms.admin.service.res.PageResult;
import com.xoms.util.AppTextUtil;
import com.xoms.util.DateTimeUtil;
import com.xoms.util.NumUtil;
import com.xoms.util.PinYinUtil;
import com.xoms.util.StringUtil;
@Service
public class ProductServiceImpl implements ProductService {
	
	Logger logger = Logger.getLogger(this.getClass());
	
	@Autowired
	ProductCache productCacheImpl;
	
	@Autowired
	ProCategoryCache proCategoryCacheImpl;
	
	@Autowired
	ProductDao productImpl;

	@Autowired
	ProCategoryDao proCategoryImpl;

	@Autowired
	ProStockDao proStockImpl;
	

	@Override
	public PageResult<RProductBean> getProducts(AccountBean account, String key, int page, int pagesize, String cid, String type) {
		PageResult<RProductBean> result = new PageResult<RProductBean>();
		List<RProductBean> resList = new ArrayList<RProductBean>();
		// 获取商品数量
		int count = productImpl.selectCount(key, cid, type);
		if(count > 0) {
			//查询商品列表
			List<ProductBean> lists = productImpl.selectList(key, page, pagesize, cid, type);

			if (lists != null) {
				RProductBean rb = null;
				for (ProductBean acc : lists) {
					rb=parse(acc);
					resList.add(rb);
				}
			}
		}
		
		result.setData(resList);
		result.setCount(count);
		return result;
	}

	/**
	 * 格式化商品数据
	 * @param acc
	 * @return
	 */
	private RProductBean parse(ProductBean pro) {
		RProductBean res = new RProductBean();
		res.setAccount(pro.getAccountId());
		res.setPid(pro.getPid());
		res.setName(pro.getName());
		res.setCategory(pro.getCategory());
		res.setImgUrl(pro.getImgUrl());
		res.setSpecs(pro.getSpecs());
		res.setUnit(pro.getUnit());
		res.setProductBar(pro.getProductBar());
		res.setProductNo(pro.getProductNo());
		res.setRemark(pro.getRemark());
		res.setAccount(pro.getAccount());
		res.setPrice(pro.getPrice());
		res.setUnitId(pro.getUnitId() + "");
		res.setCategoryArr(pro.getCategoryArr());
		res.setSaleStatus(pro.getSaleStatus());
		res.setStartTime(DateTimeUtil.formatTimestamp(pro.getStartTime()));
		res.setEndTime(DateTimeUtil.formatTimestamp(pro.getEndTime()));
		res.setCreateTime(DateTimeUtil.formatTimestamp(pro.getCreateTime()));
		return res;
	}

	@Transactional(rollbackFor = Exception.class)// 事务
	@Override
	public RProductDetailBean edit(AccountBean account, String pid, String name, String productBar, String categoryArr,
			String imgUrl, String specs, int unitId, String status, int warnNum, String remark,
			int type, int maxNum, int costType, String groups, double anitPrice) {
		boolean flag = false;
		ProductBean data = new ProductBean();
		data.setName(name);
		data.setProductBar(productBar);
		data.setImgUrl(imgUrl);
		data.setSpecs(specs);
		data.setUnitId(unitId);
		data.setStatus(status);
		data.setWarnNum(warnNum);
		data.setMaxNum(maxNum);
		data.setCostType(costType);
		data.setRemark(remark);
		data.setAntiPrice(anitPrice);
		data.setCategoryArr(categoryArr);
		// 从数组内获取第三个值存入数据库
		JSONArray cateArr = JSON.parseArray(categoryArr);
		if(cateArr != null) {
			String categoryId = cateArr.getString(cateArr.size() - 1);  
			data.setCategoryId(categoryId);
		}
		data.setType(type);

		if (StringUtil.isEmpty(pid)) {// 新建
			// 新建时验证商品是否已存在
			int temp = productImpl.selectProCountByName(name);
			if (temp > 0) {
				throw new ServiceException("product_name_is_exist");
			}
			int barNum = productImpl.selectCountByProBar(productBar);
			if (barNum > 0) {
				throw new ServiceException("product_bar_is_exist");
			}
			pid = AppTextUtil.getPrimaryKey();
			data.setPid(pid);
			data.setAccountId(account.getAccid());
			
			// 商品编号：PRO + YYYYMMDDHHmmss + 00001;
			String maxNo = productImpl.selectMaxProNo();
			int num = 0;
			if(!StringUtil.isEmpty(maxNo)) {
				num = NumUtil.toInt(maxNo.substring(maxNo.length() - 5, maxNo.length()), 0);
			}
			String productNo = AppTextUtil.getRandomProNo("Pro", (num+1), 5);
			data.setProductNo(productNo);
			
			data.setInitial(PinYinUtil.getAllFirstChar(name));
			flag = productImpl.insert(data) > 0;
			if (!flag) {
				throw new ServiceException("database_insert_fail","商品信息");
			}
		} else {
			// TODO: 判断当前id是否有值
			data.setPid(pid);
			flag = productImpl.update(data) > 0;// 更新数据库
			if (!flag) {
				throw new ServiceException("database_update_fail","商品信息");
			}
			// 更新数据时，如果是有组合商品则删除
			if(productImpl.selectGroupCount(pid) > 0) {// 判断组合商品数量
				// 根据商品id删除商品组合列表
				flag = productImpl.delGroupByProId(pid) > 0;
				if (!flag) {
					throw new ServiceException("database_delete_fail","商品组合详情");
				}
			}
		}
		
		// 组合商品不为空，将组合商品列表批量插入数据库
		if(!StringUtil.isEmpty(groups)) { 
			flag = insertBatchGroup(pid, account.getAccid(), groups);
		}
		return parseDetail(productImpl.selectOneById(data.getPid()));
	}

	
	/**
	 * 
	 * @param pid
	 * @param groups
	 * @return
	 */
	private boolean insertBatchGroup(String pid, String accountId, String groups) {
		boolean flag = false;
		// JSON转list
		List<BatchProGroupBean> batch = JSON.parseArray(groups, BatchProGroupBean.class);
		for(BatchProGroupBean group : batch) {
			group.setPid(pid);
			group.setAccountId(accountId);
		}
		if(batch.size() > 0) {
			flag = productImpl.insertBatchGroup(batch) > 0;
			if (!flag) {
				throw new ServiceException("database_insert_fail","组合商品");
			}
		}
		return flag;
	}

	@Override
	public RProductDetailBean getDetail2Pid(AccountBean account, String productId) {
		RProductDetailBean result = new RProductDetailBean();
		//查询商品
		ProductDetailBean product = productImpl.selectOneById(productId);
		if (product != null) {
			result = parseDetail(product);
		}
		return result;
	}
	
	/**
	 * 格式化商品详情
	 * @param pro
	 * @return
	 */
	private RProductDetailBean parseDetail(ProductDetailBean pro) {
		RProductDetailBean res = new RProductDetailBean();
		res.setAccount(pro.getAccountId());
		res.setPid(pro.getPid());
		res.setName(pro.getName());
		res.setCategory(pro.getCategory());
		res.setImgUrl(pro.getImgUrl());
		res.setSpecs(pro.getSpecs());
		res.setUnit(pro.getUnit());
		res.setProductBar(pro.getProductBar());
		res.setProductNo(pro.getProductNo());
		res.setRemark(pro.getRemark());
		res.setAccount(pro.getAccount());
		res.setPrice(pro.getPrice());
		res.setStatus(pro.getStatus());
		res.setUnitId(pro.getUnitId() + "");
		res.setCategoryArr(pro.getCategoryArr());
		res.setCostType(pro.getCostType());
		res.setMaxNum(pro.getMaxNum());
		res.setWarnNum(pro.getWarnNum());
		res.setSaleStatus(pro.getSaleStatus());
		res.setStartTime(DateTimeUtil.formatTimestamp(pro.getStartTime()));
		res.setEndTime(DateTimeUtil.formatTimestamp(pro.getEndTime()));
		res.setCreateTime(DateTimeUtil.formatTimestamp(pro.getCreateTime()));
		List<ProGroupBean> details = pro.getDetails();
		List<RProGroupBean> resGroups = new ArrayList<>();
		if(details != null && details.size() > 0) {
			for(ProGroupBean group : details) {
				RProGroupBean rp = new RProGroupBean();
				rp = parsGroup(group);
				resGroups.add(rp);
			}
		}
		res.setGroups(resGroups);
		return res;
	}
	
	/**
	 * 格式化组合商品
	 * @param group
	 * @return
	 */
	private RProGroupBean parsGroup(ProGroupBean group) {
		RProGroupBean res = new RProGroupBean();
		res.setAccount(group.getAccount());
		res.setMaterial(group.getMaterial());
		res.setMaterialId(group.getMaterialId());
		res.setNumber(group.getNumber());
		res.setProduct(group.getMaterial());
		res.setProductId(group.getMaterialId());
		res.setRemark(group.getRemark());
		res.setUnit(group.getUnit());
		res.setUnitId(group.getUnitId());
		res.setCreateTime(DateTimeUtil.formatTimestamp(group.getCreateTime()));
		return res;
	}

	@Override
	public PageResult<RProductBean> getProduct2NameBar(AccountBean account, String name, String productBar) {
		PageResult<RProductBean> result = new PageResult<RProductBean>();
		List<RProductBean> resList = new ArrayList<RProductBean>();
		// 根据名称或条形码获取商品数量
		int count = productImpl.selectProCountByNameBar(name, productBar);
		if(count > 0) {
			//根据名称或条形码查询列表
			List<ProductBean> lists = productImpl.selectProductByNameBar(name, productBar);

			if (lists != null) {
				RProductBean rb = null;
				for (ProductBean acc : lists) {
					rb=parse(acc);
					resList.add(rb);
				}
			}
		}
		result.setCount(count);
		result.setData(resList);
		return result;
	}

	@Override
	public RProJSONBean getSellList(AccountBean account) {
		RProJSONBean bean = new RProJSONBean();
		JSONArray jsonArray = new JSONArray();
		// 从缓存获取所有分类
		String cateStr = null;//proCategoryCacheImpl.getCategoresCache();
		if (StringUtil.isEmpty(cateStr)) {// redis内分类信息为空则从数据库查询分类

			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_HQ);
			
			List<TreeNodeBean> cates = proCategoryImpl.selectHqCateTrees(null);
			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_XOMS);
			
			List<TreeNodeBean> cates2 = proCategoryImpl.selectCategores();
			if(cates2 == null) {
				return null;
			}
			cates.addAll(cates2);
			// 查询商品列表
			List<ProTreeNodeBean> products = null;
			String pcatch = null;//productCacheImpl.getSellProductsCache();
			if (StringUtil.isEmpty(cateStr)) { 
				products = productImpl.selectSellProducts();
				String productsJson = JSON.toJSONString(products, SerializerFeature.WriteMapNullValue);
				productCacheImpl.setSellProductCache(productsJson);
			} else {
				products = JSON.parseArray(pcatch, ProTreeNodeBean.class);
			}
			if(products == null) {
				return null;
			}
			cates.addAll(products);
			
		    logger.info("cates分类："+JSON.toJSONString(cates));
			// 构造根节点
			TreeNodeBean root = new TreeNodeBean();
			root.setValue("0");
			cates.add(root);
			// 根据父节点id分组
		    Map<String, List<TreeNodeBean>> map = cates.stream()
		            .filter(o -> Objects.nonNull(o.getParentId()))
		            .collect(Collectors.groupingBy(TreeNodeBean::getParentId));

		    //循环处理子节点 构建树状结构
		    cates.forEach(proCategory -> {
		        if (map.containsKey(proCategory.getValue())) {
		        		proCategory.setChildren(map.get(proCategory.getValue()));
		        } 
		    });
			// 获取根节点下的所有服务项
		    TreeNodeBean result = cates.stream()
		    		.filter(proCategory -> "0".equals(proCategory.getValue())).findFirst().orElse(null);
			String catesJson = JSON.toJSONString(result.getChildren(), SerializerFeature.WriteMapNullValue);
			jsonArray = JSON.parseArray(catesJson);
			// 将分类存入缓存
			//proCategoryCacheImpl.setCategoryCache(catesJson);
		} else {
			jsonArray = JSON.parseArray(cateStr);
		}
		bean.setProduct(jsonArray);
		return bean;
	}

	@Override
	public boolean editSorts2Product(String sorts) {
		boolean flag = false;
		List<String> sortList = JSON.parseArray(sorts, String.class);
		flag = productImpl.updateSorts(sortList) > 0;
		productCacheImpl.setSellProductCache(null);
		return flag;
	}

	@Override
	public RProSelectJSONBean getSelectList(AccountBean account, int type) {
		RProSelectJSONBean bean = new RProSelectJSONBean();
		JSONArray jsonArray = new JSONArray();
		// 从缓存获取分类下商品
		String proStr = null;//productCacheImpl.getSelectProductsCache(type);
		List<TreeNodeBean> products = null;
		if (StringUtil.isEmpty(proStr)) {// redis内分类信息为空则从数据库查询分类
			// 查询商品列表
			products = productImpl.selectSelectProducts(type);
			String productsJson = JSON.toJSONString(products, SerializerFeature.WriteMapNullValue);
			productCacheImpl.setSellProductCache(productsJson);
			if(products == null) {
				return null;
			}
			
		    logger.info("商品JSON："+JSON.toJSONString(products));
			// 获取根节点下的所有服务项
			jsonArray = JSON.parseArray(productsJson);
			// 将分类存入缓存
			//proCategoryCacheImpl.setSelectProductCache(catesJson, type);
		} else {
			jsonArray = JSON.parseArray(proStr);
		}
		bean.setProduct(jsonArray);
		return bean;
	}

	@Override
	public boolean delProduct(AccountBean account, String pid) {
		boolean flag = false;
		// 判断仓库内是否有商品，存在则无法删除
		int proStore = proStockImpl.selectStore2Pro(pid);
		if(proStore > 0) {
			throw new ServiceException("product_has_in_store");
		}
		flag = productImpl.delProduct(pid) > 0;
		if(proStore > 0) {
			throw new ServiceException("database_delete_fail", "商品");
		}
		return flag;
	}

}
